package top.codetheory.thread._008_CAS;

import com.sun.org.apache.xpath.internal.WhitespaceStrippingElementMatcher;
import java.lang.reflect.Field;
import lombok.extern.slf4j.Slf4j;
import sun.misc.Unsafe;

/**
 * @author:
 * @since: 2024/6/2 上午12:31
 **/
@Slf4j
public class _002_Unsafe类 {
    public static void main(String[] args) {
        Unsafe unsafe = UnsafeAccessor.getUnsafe();
        log.info("{}", unsafe);
        Unsafe newUnsafe = UnsafeAccessor.newGetUnsafe();
        log.info("{}", newUnsafe);
    }
}

/**
 * 获取Unsafe对象的工具类
 */
class UnsafeAccessor {
    static Unsafe unsafe;

    static {
        try {
            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
            theUnsafe.setAccessible(true); // 允许获取私有变量
            unsafe = (Unsafe) theUnsafe.get(null);  // 这里需要传获取的对象，因为是静态变量，所以传null
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    static Unsafe getUnsafe() {
        return unsafe;
    }

    static Unsafe newGetUnsafe() {
        return Unsafe.getUnsafe();
    }
}

/**
 * 模拟实现原子整数
 */
class AtomicDate {
    private volatile int value;
    static final Unsafe unsafe;
    static final long valueOffset;

    static {
        unsafe = UnsafeAccessor.getUnsafe();
        try {
            // 获取value属性在AtomicDate对象中的偏移量，用于Unsafe直接访问该属性
            valueOffset = unsafe.objectFieldOffset(AtomicDate.class.getDeclaredField("value"));
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    public AtomicDate(int value) {
        this.value = value;
    }

    public void decrease(int num) {
        int prev;
        while(true) {
            prev = value;  // 获取旧值
            if (unsafe.compareAndSwapInt(this, valueOffset, prev, num)) {  // 这几个参数的含义：需要比较的对象，需要比较的属性偏移量，旧值，期望值
                break;
            }
        }
    }

    public int getValue() {
        return value;
    }
}